package com.martini.satoken01.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.martini.satoken01.entity.SysUser;
import com.martini.satoken01.model.AjaxJson;
import com.martini.satoken01.model.domain.OnlineInfoDO;
import com.martini.satoken01.model.mapper.OnlineInfoModelMapper;
import com.martini.satoken01.model.mapper.SysUserEntityMapper;
import com.martini.satoken01.model.vo.OnlineInfoVO;
import com.martini.satoken01.service.system.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author martini at 2021/12/17 11:43
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    private final UserService userService;

    private final SysUserEntityMapper sysUserEntityMapper;

    private final OnlineInfoModelMapper onlineInfoModelMapper;

    public UserController(UserService userService, SysUserEntityMapper sysUserEntityMapper, OnlineInfoModelMapper onlineInfoModelMapper) {
        this.userService = userService;
        this.sysUserEntityMapper = sysUserEntityMapper;
        this.onlineInfoModelMapper = onlineInfoModelMapper;
    }

    @GetMapping
    @SaCheckLogin
    public AjaxJson getLoginSysUserInfo(@RequestHeader("User-Agent") String uaStr) {
        long loginId = Long.parseLong(Objects.requireNonNull(StpUtil.getLoginId()).toString());
        SysUser sysUser = userService.findUserById(loginId);
        return AjaxJson.success().setData(sysUserEntityMapper.toSysUserVO(Objects.requireNonNull(sysUser)));
    }

    @PostMapping("/sendValidationCode")
    @SaCheckLogin
    public AjaxJson sendValidationCode() {
        long loginId = Long.parseLong(Objects.requireNonNull(StpUtil.getLoginId()).toString());
        boolean sent = userService.sendValidationEmail(loginId);
        return sent ? AjaxJson.success().setMsg("发送成功，注意查收邮件") : AjaxJson.fail().setMsg("发送错误，检查邮件地址无误后，请联系管理员");
    }

    @PostMapping("/checkValidationCode")
    @SaCheckLogin
    public AjaxJson checkValidationCode(@RequestParam String code) {
        long loginId = Long.parseLong(Objects.requireNonNull(StpUtil.getLoginId()).toString());
        boolean checked = userService.checkEmailValidationCode(loginId, code);
        return checked ? AjaxJson.success().setMsg("验证成功") : AjaxJson.fail().setMsg("验证失败，请检查验证码是否有错误");
    }

    @PostMapping("/update")
    @SaCheckLogin
    public AjaxJson updateUser(@RequestBody SysUser sysUser) {
        boolean updatedSuccessfully = this.userService.updateByPrimaryKeySelective(sysUser);
        return updatedSuccessfully ? AjaxJson.success().setMsg("更新成功") : AjaxJson.fail().setMsg("更新失败");
    }

    @GetMapping("/online")
    @SaCheckLogin
    public AjaxJson getUserOnlineInfo(@RequestHeader("User-Agent") String uaStr) {
        List<OnlineInfoDO> onlineInfoList = this.userService.getOnlineInfo(StpUtil.getLoginIdAsLong());
        UserAgent ua = UserAgentUtil.parse(uaStr);
        String device = ua.getPlatform().toString();
        List<OnlineInfoVO> onlineInfoVOList = onlineInfoList.stream().map(i -> {
            OnlineInfoVO onlineInfoVO = onlineInfoModelMapper.toOnlineInfoVO(i);
            onlineInfoVO.setMyself(Objects.equals(i.getDevice(), device));
            return onlineInfoVO;
        }).collect(Collectors.toList());
        return AjaxJson.success().setData(onlineInfoVOList);
    }

    @PostMapping("/kickOut")
    @SaCheckLogin
    public AjaxJson kickOutDevice(@RequestHeader("User-Agent") String uaStr,
                                  @RequestParam("device") String device) {
        UserAgent ua = UserAgentUtil.parse(uaStr);
        String curDevice = ua.getPlatform().toString();
        if (Objects.equals(curDevice, device)) {
            return AjaxJson.fail().setMsg("不能踢自己下线");
        }
        this.userService.offline(StpUtil.getLoginIdAsLong(), device);
        StpUtil.kickout(StpUtil.getLoginId(), device);
        return AjaxJson.success().setMsg("操作成功");
    }
}
